package ar.com.spsolutions.splibrary.services.dto;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;

import ar.com.spsolutions.splibrary.author.Author;
import ar.com.spsolutions.splibrary.book.Book;
import ar.com.spsolutions.splibrary.book.category.Category;
import ar.com.spsolutions.splibrary.services.BookService;

public class CRUDBookDTO extends AbstractCRUDDTO<Book> {

	private static final long serialVersionUID = 1783211310681870394L;
	private static final String TITLE = "title";
	private static final String PUBLISHER = "publisher";
	private static final String DESCRIPTION = "description";
	private static final String AUTHOR = "author";
	private static final String CATEGORIES = "categories";
	private static final String ISBN = "isbn";

	public CRUDBookDTO() {
		super();
		final Map<String, String> properties = this.getRendererProperties();
		properties.put("author", "name");
		properties.put(CRUDBookDTO.CATEGORIES, "name");
	}

	public BookService getBookService() {
		return this.getLibraryServiceFacade().getEntityService()
				.getBookService();
	}

	// -- dto accesors --
	public String getTitle() {
		return this.getPropertyValue(CRUDBookDTO.TITLE);
	}

	public List<Category> getCategories() {
		final List<Category> propertyValue = this
				.getPropertyValue(CRUDBookDTO.CATEGORIES);
		return propertyValue;
	}

	public void fromCategoriesAdd(final Category cat) {
		final List<Category> categories = this
				.getPropertyValue(CRUDBookDTO.CATEGORIES);
		if (!categories.contains(cat)) {
			categories.add(cat);
		}
	}

	public List<Category> allCategories() {
		final List<Category> findAll = this.getLibraryServiceFacade()
				.getEntityService().getCategoryService().findAll();
		return findAll;
	}

	public String getPublisher() {
		return this.getPropertyValue(CRUDBookDTO.PUBLISHER);
	}

	public String getIsbn() {
		return this.getPropertyValue(CRUDBookDTO.ISBN);
	}

	public String getDescription() {
		return this.getPropertyValue(CRUDBookDTO.DESCRIPTION);
	}

	public Author getAuthor() {
		final Author author = this.getPropertyValue(CRUDBookDTO.AUTHOR);
		return this.getLibraryServiceFacade().attachSession(author);
	}

	public void setTitle(final String value) {
		this.setPropertyValue(CRUDBookDTO.TITLE, value);
	}

	public void setIsbn(final String value) {
		this.setPropertyValue(CRUDBookDTO.ISBN, value);
	}

	public void setCategories(final List<Category> value) {
		this.setPropertyValue(CRUDBookDTO.CATEGORIES, value);
	}

	public void setDescription(final String value) {
		this.setPropertyValue(CRUDBookDTO.DESCRIPTION, value);
	}

	public void setPublisher(final String value) {
		this.setPropertyValue(CRUDBookDTO.PUBLISHER, value);
	}

	public void setAuthor(final Author value) {
		this.setPropertyValue(CRUDBookDTO.AUTHOR, value);
	}

	public List<Author> getAuthors() {
		return this.getLibraryServiceFacade().findAllAuthors();
	}

	private Map<String, String> rendererProperties = new HashMap<String, String>();

	public Map<String, String> getRendererProperties() {
		return this.rendererProperties;
	}

	// -- overrides --
	@Override
	public String getRenderPropertyFor(final String id) {
		return this.getRendererProperties().get(id);
	}

	@Override
	public int allResultsSize() {
		return this.getBookService().sizeOfSearch(this.getSearchValue());

	}

	@Override
	public Iterator<? extends Book> getResults(final String searchValue,
			final int first, final int count) {
		return this.getBookService().getResults(searchValue, first, count)
				.iterator();
	}

	@Override
	public void delete(final Book book) {
		this.getLibraryServiceFacade().delete(book);
	}

	@Override
	protected void update(final Book book) {
		this.getLibraryServiceFacade().update(book);
	}

	@Override
	@Transactional
	protected void save(final Book book) {
		this.getLibraryServiceFacade().add(book);

	}

	@Override
	protected Book getNewEntity() {
		return new Book();
	}

	@Override
	protected void setPrimaryKeyInNewEntity(final Book entity,
			final String primaryKey) {
		entity.setTitle(primaryKey);
	}

	public void setRendererProperties(
			final Map<String, String> rendererProperties) {
		this.rendererProperties = rendererProperties;
	}

}
